//-< CodeGenerator.java >--------------------------------------------*--------*
// JSQL                       Version 1.04       (c) 1999  GARRET    *     ?  *
// (Java SQL)                                                        *   /\|  *
//                                                                   *  /  \  *
//                          Created:     23-Mar-2009  K.A. Knizhnik  * / [] \ *
//                          Last update: 23-Mar-2009  K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// JQSL query generator
//-------------------------------------------------------------------*--------*

package org.garret.perst;

/**
 * Code generator for JSQL queries.
 */
public interface CodeGenerator
{
    /**
     * Class representing abstract syntax tree generated by query code generator
     */
    public interface Code {}

    /**
     * Set query predicate code
     * @param code AST constructed using CodeGenerator methods
     */
    void predicate(Code code);
                                                
    /**
     * Literal constant 
     */
    Code literal(Object value);
    
    /**
     * List of alternatives for IN operator 
     */
    Code list(Code... values);

    /**
     * Query parameter
     * @param n parameter index (0 based)
     * @param type parameter type
     */
    Code parameter(int n, Class type);

    /**
     * Get self field
     * @param name field name     
     */
    Code field(String name);

    /**
     * Get field
     * @param base target object
     * @param name field name     
     */
    Code field(Code base, String name);

    /**
     * Invoke method
     * @param base invocation  target
     * @param name method name
     * @param arguments method arguments
     */
    Code invoke(Code base, String name, Code... arguments);

    /**
     * Invoke self method
     * @param name method name
     * @param arguments method arguments
     */
    Code invoke(String name, Code[] arguments);

    Code and(Code left, Code right);
    Code or(Code left, Code right);

    Code add(Code left, Code right);
    Code sub(Code left, Code right);
    Code mul(Code left, Code right);
    Code div(Code left, Code right);
    Code pow(Code left, Code right);

    Code eq(Code left, Code right);
    Code ge(Code left, Code right);
    Code gt(Code left, Code right);
    Code lt(Code left, Code right);
    Code le(Code left, Code right);
    Code ne(Code left, Code right);

    Code neg(Code expr);
    Code abs(Code expr);
    Code not(Code expr);

    Code between(Code expr, Code low, Code high);
    Code like(Code expr, Code pattern, Code esc);
    Code like(Code expr, Code pattern);
    Code in(Code expr, Code set);

    Code sin(Code expr);
    Code cos(Code expr);
    Code tan(Code expr);
    Code asin(Code expr);
    Code acos(Code expr);
    Code atan(Code expr);
    Code sqrt(Code expr);
    Code exp(Code expr);
    Code log(Code expr);
    Code ceil(Code expr);
    Code floor(Code expr);

    /**
     * Convert string to lower case
     */
    Code lower(Code expr);

    /**
     * Convert string to upper case
     */
    Code upper(Code expr);

    /**
     * Get array length
     */
    Code length(Code expr);

    /**
     * Get array element
     */
    Code getAt(Code array, Code index);

    /**
     * Convert real to integer
     */
    Code integer(Code expr);

    /**
     * Convert integer to real
     */
    Code real(Code expr);

    /**
     * Convert integer/real/date to string
     */
    Code string(Code expr);

    /**
     * Add order by clause. It is possible to invoke this method several times - in this case
     * result will be sorted by all specified fields in the correspondent order
     * @param name field name by which sort should be performed
     * @param ascent true for ascent order, false for descent order
     */
    void orderBy(String name, boolean ascent);

    /**
     * Add order by clause. It is possible to invoke this method several times - in this case
     * result will be sorted by all specified fields in the correspondent order
     * @param name field name by which sort should be performed
     */
    void orderBy(String name);
}